/*
 * Protocolo.cpp
 *
 * Author: Grupo Nro.
 */

#include "Protocolo.h"

Protocolo::Protocolo() {
}

Protocolo::~Protocolo() {
}

bool Protocolo::recvAll(int sockfd, string & mensajeRecibido, string & codigoMensaje){
	//Con lo que viene en la primer lectura se sabe la longitud del mensaje
	bool recibeOk = true;
	char bufferTam[CANT_BYTES_PRIMER_MENSAJE];

	unsigned long int bytesRecibidos = 0;
	long int bytesPendientes = CANT_BYTES_PRIMER_MENSAJE - 1;
	long int bytes = 0;
	while (bytesRecibidos < (CANT_BYTES_PRIMER_MENSAJE - 1) && recibeOk){
		bytes = recv(sockfd, bufferTam+bytesRecibidos, bytesPendientes, 0);
		if (bytes <= 0){
			recibeOk = false;
		} else {
			bytesRecibidos += bytes;
			bytesPendientes -= bytes;
		}
	}

	if (recibeOk){
		//No hubo error en la recepcion del mensaje,
		//continuo esperando mensajes
		bufferTam[CANT_BYTES_PRIMER_MENSAJE - 1] = '\0';
		string primerMensaje = string(bufferTam);

		unsigned int tamanioMensaje = strtoul(primerMensaje.substr(2, 5).c_str(), NULL, 10);
		codigoMensaje = primerMensaje.substr(0, 2);

		if (tamanioMensaje <= 0){
			mensajeRecibido = "";
			return recibeOk;
		}

		char * buffer = new char[tamanioMensaje + 1];//Uno mas para el fin de cadena

		bytesRecibidos = 0;
		bytesPendientes = tamanioMensaje;
		bytes = 0;
		while (bytesRecibidos < tamanioMensaje && recibeOk){
			bytes = recv(sockfd, buffer+bytesRecibidos, bytesPendientes, 0);
			if (bytes <= 0){
				recibeOk = false;
			} else {
				bytesRecibidos += bytes;
				bytesPendientes -= bytes;
			}
		}
		//Agrego fin de cadena
		buffer[tamanioMensaje] = '\0';

		//Cargo el mensaje
		if (recibeOk){
			mensajeRecibido = "";
			mensajeRecibido.append(buffer);
		}

		//Libero recurso
		if (buffer != NULL){
			delete [] buffer;
			buffer = NULL;
		}
	}

	return recibeOk;
}

bool Protocolo::sendAll(int sockfd, const string & mensaje){
	bool envioOk = true;
	//Mando la cadena
	unsigned long int bytesEnviados = 0;
	unsigned int bytesPendientes = mensaje.size();
	long int bytes = 0;
	while (bytesEnviados < mensaje.size() && envioOk){
		bytes = send(sockfd, mensaje.c_str()+bytesEnviados, bytesPendientes, 0);
		if (bytes == -1){
			envioOk = false;
		} else {
			bytesEnviados += bytes;
			bytesPendientes -= bytes;
		}
	}

	return envioOk;
}

string Protocolo::mensajeErrorMensajeInicial(int sockfd){
	string mensajeError = "No se puede recibir mensaje inicial para tener cliente ok. Sockfd:";
	mensajeError.append(Utils::pasarLongACadena(sockfd));

	return mensajeError;
}

string Protocolo::mensajeErrorCodigo(string codigoMensaje, int sockfd){
	string mensajeError = "Error en el código del mensaje recibo. Codigo recibido:";
	mensajeError.append(codigoMensaje.c_str());
	mensajeError.append(". Sockfd:");
	mensajeError.append(Utils::pasarLongACadena(sockfd));

	return mensajeError;
}

